use crate::db::{
    dao::BaseDao,
    po::endpoint_peer::{ActiveModel, Column, Entity, Model},
};
use sea_orm::{ColumnTrait, DatabaseConnection};
use sea_query::IntoCondition;

#[derive(Debug, Default, Clone, Eq, PartialEq)]
pub struct Filter {
    pub endpoint_peer_id: Option<String>,
    pub endpoint_id: Option<String>,
    pub peer_endpoint_id: Option<String>,
}

impl IntoCondition for Filter {
    fn into_condition(self) -> sea_query::Condition {
        let mut condition = sea_query::Condition::all();

        if let Some(endpoint_peer_id) = self.endpoint_peer_id {
            condition = condition.add(Column::EndpointPeerId.eq(endpoint_peer_id));
        }

        if let Some(endpoint_id) = self.endpoint_id {
            condition = condition.add(Column::EndpointId.eq(endpoint_id));
        }

        if let Some(peer_endpoint_id) = self.peer_endpoint_id {
            condition = condition.add(Column::PeerEndpointId.eq(peer_endpoint_id));
        }
        condition
    }
}

#[async_trait::async_trait]
pub trait EndpointPeerDao:
    BaseDao<Model = Model, ActiveModel = ActiveModel, Entity = Entity, Column = Column, Filter = Filter>
{
}

#[derive(Clone)]
pub struct DefaultEndpointPeerDao {
    db: DatabaseConnection,
}

impl DefaultEndpointPeerDao {
    pub fn new(db: DatabaseConnection) -> Self {
        Self { db }
    }
}

#[async_trait::async_trait]
impl BaseDao for DefaultEndpointPeerDao {
    type Model = Model;
    type ActiveModel = ActiveModel;
    type Entity = Entity;
    type Column = Column;
    type Filter = Filter;

    fn db(&self) -> &DatabaseConnection {
        &self.db
    }
}

#[async_trait::async_trait]
impl EndpointPeerDao for DefaultEndpointPeerDao {}
